package com.tuxianchao.springbootweblogaspeact.util;

import javax.servlet.http.HttpServletRequest;

/**
 * created by
 * 获取真实ip
 * <p>
 * 通过request获取客户端IP时，自身服务器通常会为了保护信息或者负载均衡的目的，对自身服务器做反向代理。
 * 如果通过request.getRemoteAddr();
 * 可能获取到的是自身代理服务器的IP，而无法达到获取用户请求ip的目的
 * <p>
 * <p>
 * 整理了各个代理服务器自己开发的转发服务请求头，这些请求头都不是标准的http请求头，
 * 不一定所有的代理都会带上这些请求头，
 * 通过这方式只能尽可能的获取到真实ip，但不能保证一定可以获取到真实ip，而且代理服务器请求头中获取的ip是可伪造的
 *
 * @author tuxianchao
 * @date 2018/5/12 下午12:16
 */
public class IpAddressUtil {
    public static String getIpAddress(HttpServletRequest request) {
        String realIp = null;

        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            realIp = ipAddresses.split(",")[0];
        }

        //如果还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (realIp == null || realIp.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            realIp = request.getRemoteAddr();
        }
        return realIp;
    }
}
